/*
 * @Author: wangtianyu wangtianyu@lierda.com
 * @Date: 2023-12-04 11:30:55
 * @LastEditors: wangtianyu wangtianyu@lierda.com
 * @LastEditTime: 2024-01-19 20:20:37
 * @FilePath: \kcm_c3_v1_0\lib\Application\Games\GreedySnake.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

#include "GreedySnake.h"

#include "kkgui_app.h"
#include "kkgui_base.h"
#include "kkgui_key.h"

const uint8_t home_page_snake[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xB0,0x50,0xD0,0x90,0x20,0x30,0x50,0x10,0x98,0x4C,0x44,0xF4,0xF6,0x12,0x92,0x0E,0x08,0x08,0x18,0x10,0x10,0x10,0x10,0x30,
0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0xA0,0x50,0xB0,0x50,0xB0,0x58,0xA8,0x54,0xAC,0xD4,0xAC,0xD6,0x6A,
0x56,0x6B,0x55,0x6B,0x35,0x2B,0x35,0x3B,0x7D,0xDB,0x9F,0x9F,0x97,0x15,0x16,0x13,0x12,0x11,0x11,0x10,0x13,0xA2,0x81,0x40,0xC2,0x42,0x60,0x20,0xA1,0xE0,0x20,0x22,
0x23,0x31,0x17,0x1D,0x90,0xF0,0x70,0xB0,0x50,0xBF,0x5E,0xB0,0x50,0xA0,0x60,0xA0,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x20,0x20,0x70,0xB0,0xDC,0xAF,0xD5,0xAA,0x55,0xA6,0x45,0xCA,0x7D,
0xFA,0x77,0x25,0x3C,0x76,0xAB,0xFD,0xF7,0x60,0xE0,0x40,0xC0,0x40,0xC0,0x40,0xC0,0x40,0xC3,0x44,0x04,0x49,0x2F,0x31,0x9F,0x7F,0x01,0x81,0xC1,0x61,0x32,0x1C,0x0F,
0x06,0x06,0x03,0x81,0xC0,0x60,0x30,0x18,0x8C,0xC6,0x63,0x31,0x19,0x09,0x0D,0x05,0xC7,0xC5,0x42,0xE3,0xA3,0xA1,0x71,0xD1,0xB1,0x51,0xB1,0x51,0xF1,0x11,0x23,0x42,
0x82,0x04,0x04,0x0C,0x30,0xF0,0x98,0xA8,0xE4,0xC4,0x84,0x08,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x68,0x75,0x77,0x57,0xAB,0xDF,0xBA,
0x75,0xFB,0x75,0xFA,0xF5,0xFA,0xFD,0xF9,0xCD,0x09,0x1A,0x2D,0x8A,0x4D,0x3A,0x55,0x5A,0x4D,0xCA,0x0D,0x5A,0x4D,0x26,0x9F,0x17,0x83,0x80,0xE0,0x30,0x18,0x0C,0x06,
0x03,0x81,0xC0,0x60,0x30,0x98,0xCC,0xCC,0xE7,0xE3,0xE1,0xE0,0x00,0xFC,0x87,0x01,0x00,0x00,0x38,0x6C,0xC6,0x83,0x85,0x76,0x76,0x21,0x55,0xAC,0xCE,0x8E,0x8F,0x9E,
0x9D,0x1A,0x1D,0x1F,0x1F,0x1F,0x17,0x17,0x18,0x14,0x98,0x9C,0xCF,0xCE,0xAC,0x4D,0xA5,0xD1,0xFF,0xFC,0xE0,0x00,0x00,0x01,0x0E,0x7A,0xCC,0x00,0xF0,0xF8,0xF8,0xF8,
0xFC,0xFC,0xFC,0xFE,0xFD,0xFD,0xF9,0xF3,0xE6,0xCD,0x9A,0x35,0x6B,0xD7,0x87,0xDB,0xD3,0xF1,0xF9,0xFE,0xFC,0xEA,0xD9,0x6F,0x38,0x83,0xFF,0xFF,0xFF,0xFF,0x00,0x7E,
0xFF,0xC3,0x80,0x00,0x00,0x70,0x1C,0x1F,0x11,0x30,0x26,0x6F,0x4F,0x5F,0x5F,0x5F,0x5F,0xDF,0x9F,0xBE,0xBC,0xB9,0xB3,0x86,0xCC,0x58,0x70,0x20,0x19,0x03,0x07,0x06,
0x0C,0x39,0xE2,0x0D,0xA8,0x50,0x10,0x11,0x31,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x11,0x51,0x14,0xB2,0x5D,0xAA,0xD5,0xFA,0x27,0xC7,0x9F,0x9F,0xFF,0x80,0x80,0x80,
0x40,0x3F,0x80,0x00,0x01,0x01,0x03,0x03,0x03,0x07,0x07,0x07,0x07,0x07,0x0F,0x0F,0x0F,0x0F,0x0F,0x0E,0x0E,0x0E,0x0E,0x0E,0x0C,0x08,0x07,0x0F,0x06,0x04,0x08,0x03,
0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0E,0x0E,0x0C,0x09,0x0B,0x0E,0x02,0x06,0x04,0x04,0x04,0x0C,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
0x08,0x08,0x08,0x0C,0x0C,0x0C,0x04,0x06,0x03,0x09,0x0C,0x0D,0x0D,0x0D,0x09,0x0F,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0E,0x0F,0x09,0x0D,0x0D,0x0F,0x0C,0x0E,0x0E,0x0E,
0x0E,0x06,0x06,0x07,0x06,0x02,0x02,0x03,0x03,0x01/*"E:\MCU\Project\kake-ctrl-mini\source material\snake.bmp",0*/
/* (103 X 45 )*/
};

uint8_t postion = 0;
uint8_t init_dis_pos = 0;

void snake_page_init(uint8_t pos)
{
    uiShowPicture(pos + 12, 2, 103, 45, (uint8_t *)home_page_snake, 1);
    uiDrawVLine(pos + 12 + 103, 2, 45, 0);
    uiDrawVLine(pos + 12 + 103 + 1, 2, 45, 0);
    uiShowString(pos + 12, 50, (uint8_t *)"开始 ", 12, 1);
    uiShowString(pos + 52, 50, (uint8_t *)"设置 ", 12, 1);
    uiShowString(pos + 92, 50, (uint8_t *)"记录 ", 12, 1);
    // uiDrawRBlock(pos + 11 + postion * 40, 49, 26, 14, 2, 2);
}


void Snake_Home_Loop(kkui_menu_event_e event, char* tab_name, void* param)
{    
    if(event == ENTER_TAG)
    {
        postion = 0;
        init_dis_pos = 128;
    }
    if(event == LOOP_RUN)
    {
        if(init_dis_pos) // 加载
        {
            snake_page_init(init_dis_pos);
            init_dis_pos -= 2;
        }
        else
        {        
            uiDisClear(0);
            uiShowPicture(12, 2, 103, 45, (uint8_t *)home_page_snake, 1);
            uiShowString(12, 50, (uint8_t *)"开始", 12, 1);
            uiShowString(52, 50, (uint8_t *)"设置", 12, 1);
            uiShowString(92, 50, (uint8_t *)"记录", 12, 1);
            uiDrawRBlock(11 + postion * 40, 49, 26, 14, 2, 2);
            
            if(uiKeyGetValue(UI_KEY_ENTER_ID) == DOWN || uiKeyGetValue(UI_KEY_SET_ID) == DOWN)
            {
                uiEnterAppSubList(postion);
            }
            if(uiKeyGetValue(UI_KEY_LEFT_ID) == DOWN)
            {
                if(postion > 0)
                    postion --;
            }
            if(uiKeyGetValue(UI_KEY_RIGHT_ID) == DOWN)
            {
                if(postion < 2)
                    postion ++;
            }
        }

        if(uiKeyGetValue(UI_KEY_BACK_ID) == DOWN)
        {
            uiBackAppLoop();
        }
    }
}

const char * snake_mode_name[6] =
{
    "开放", "沙盒", "开等号", "大风车", "等号", "公寓"
};
char snake_mode_name_dis[10] = "开放";
uint8_t snake_mode_select = 0;

void Snake_Set_Mode(kkui_menu_event_e event, char* tab_name, void* param)
{
    if(event == ENTER_TAG)
    {

    }
    if(event == LOOP_RUN)
    {
        if(uiKeyGetValue(UI_KEY_ENTER_ID) == DOWN || uiKeyGetValue(UI_KEY_SET_ID) == DOWN || uiKeyGetValue(UI_KEY_BACK_ID) == DOWN)
        {
            uiBackAppLoop();
        }
        if(uiKeyGetValue(UI_KEY_LEFT_ID) == DOWN || uiKeyGetValue(UI_KEY_UP_ID) == DOWN)
        {
            if(snake_mode_select > 0)
                snake_mode_select --;
            else
                snake_mode_select = 5;
        }
        if(uiKeyGetValue(UI_KEY_RIGHT_ID) == DOWN || uiKeyGetValue(UI_KEY_DOWN_ID) == DOWN)
        {
            if(snake_mode_select < 5)
                snake_mode_select ++;
            else
                snake_mode_select = 0;
        }
        memset(snake_mode_name_dis, 0, 10);
        strcpy(snake_mode_name_dis, snake_mode_name[snake_mode_select]);
    }
} 

uint8_t snake_level_select = 1;
char snake_dis_buf[2] = "1";
void Snake_Set_Level(kkui_menu_event_e event, char* tab_name, void* param)
{
    if(event == ENTER_TAG)
    {
    }
    if(event == LOOP_RUN)
    {        
        if(uiKeyGetValue(UI_KEY_ENTER_ID) == DOWN || uiKeyGetValue(UI_KEY_SET_ID) == DOWN || uiKeyGetValue(UI_KEY_BACK_ID) == DOWN)
        {
            uiBackAppLoop();
        }
        if(uiKeyGetValue(UI_KEY_LEFT_ID) == DOWN || uiKeyGetValue(UI_KEY_UP_ID) == DOWN)
        {
            if(snake_level_select > 1)
                snake_level_select --;
            else
                snake_level_select = 5;
        }
        if(uiKeyGetValue(UI_KEY_RIGHT_ID) == DOWN || uiKeyGetValue(UI_KEY_DOWN_ID) == DOWN)
        {
            if(snake_level_select < 5)
                snake_level_select ++;
            else
                snake_level_select = 1;
        }
        memset(snake_dis_buf, 0, 2);
        sprintf(snake_dis_buf, "%1d", snake_level_select);
    }
} 

const uint8_t snake_body[][6] = 
{
    {0x3C,0x38,0x38,0x38,0x3C,0x1C},/*"~",0*/
    {0x1E,0x0E,0x0E,0x0E,0x1E,0x1C},/*"^",0*/
    {0x00,0x21,0x3F,0x3F,0x3E,0x00},/*")",0*/
    {0x3E,0x3F,0x3F,0x21,0x00,0x00},/*"(",0*/
    {0x1E,0x1E,0x1F,0x0F,0x07,0x00},/*"左上",0*/
    {0x00,0x07,0x0F,0x1F,0x1E,0x1E},/*"右上",0*/
    {0x1E,0x1E,0x3E,0x3C,0x38,0x00},/*"左下",0*/
    {0x00,0x38,0x3C,0x3E,0x1E,0x1E},/*"右下",0*/

};

#define MAP_CHECK_H     16
#define MAP_BLOCK_SIZE  6

const uint8_t snake_head_l[] = {0x1F,0x15,0x0E,0x0E};
const uint8_t snake_head_r[] = {0x0E,0x0E,0x15,0x1F};
const uint8_t snake_head_d[] = {0x0C,0x0B,0x0F,0x0B,0x0C};
const uint8_t snake_head_u[] = {0x03,0x0D,0x0F,0x0D,0x03};

const uint8_t all_mode_map[][16] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"开放",0*/
{0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0xFF},/*"方盒",0*/
{0xE7,0x81,0x81,0x00,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x81,0x81,0xE7},/*"开等号",0*/ //
{0x40,0x40,0x40,0x40,0x5F,0x00,0x00,0x00,0x00,0x00,0xFA,0x02,0x02,0x02,0x02,0x02},/*"风扇",0*/ //
{0xE7,0x81,0x81,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0x81,0x81,0xE7},/*"等号",0*/ //
{0x2B,0x29,0x28,0x28,0x29,0x29,0x2F,0x21,0x21,0xE9,0x29,0x29,0x29,0x28,0x28,0x28},/*"公寓",0*/
};

#define MAP_ROAD        0
#define MAP_WALL        1
#define MAP_SNAKE_HAED  3
#define MAP_SNAKE_BODY  2
#define MAP_SNAKE_TAIL  4

#define SNAKE_DIR_START 0xC0
#define SNAKE_DIR_END   0x30
#define SNAKE_DIR_INFO  0xF0

typedef enum{
    SNAKE_S_U = 0x00 << 2, // 0000 0000
    SNAKE_S_D = 0x10 << 2, // 0100 0000
    SNAKE_S_L = 0x20 << 2, // 1000 0000
    SNAKE_S_R = 0x30 << 2, // 1100 0000
}snake_dir_start_e;

typedef enum{
    SNAKE_E_U = 0x00, // 0000 0000
    SNAKE_E_D = 0x10, // 0001 0000
    SNAKE_E_L = 0x20, // 0010 0000
    SNAKE_E_R = 0x30, // 0011 0000
}snake_dir_end_e;

typedef enum{
    SNAKE_STOP = 0,
    SNAKE_UP,
    SNAKE_DOWN,
    SNAKE_LIFT,
    SNAKE_RIGHT,
}snake_dir_act_e;

typedef struct{
    uint8_t x;
    uint8_t y;
    uint8_t dir;
}snake_body_s;

uint8_t map_data[8][16] = {0};
snake_body_s snake_body_data[128] = {0}; // 0为蛇头， snake_body_len 蛇尾
uint8_t snake_body_len = 0;
snake_dir_act_e snake_body_dir = SNAKE_STOP;

uint8_t *snake_map_mode = NULL;
uint8_t snake_game_level = 4;
uint8_t snake_time_frame = 0;
uint8_t snake_frame = 0;

void Snake_Body_Init(void) // 初始化蛇身
{
    memset(snake_body_data, 0, 128);
    snake_body_data[0].x = 7;
    snake_body_data[0].y = 4;
    snake_body_data[0].dir = SNAKE_S_L | SNAKE_E_R;
    snake_body_data[1].x = 6;
    snake_body_data[1].y = 4;
    snake_body_data[1].dir = SNAKE_S_L | SNAKE_E_R;
    snake_body_data[2].x = 5;
    snake_body_data[2].y = 4;
    snake_body_data[2].dir = SNAKE_S_L | SNAKE_E_R;
    snake_body_data[3].x = 4;
    snake_body_data[3].y = 4;
    snake_body_data[3].dir = SNAKE_S_L | SNAKE_E_R;

    snake_body_len = 3;
}

void Snake_Map_Init(uint8_t map_mode) // 初始化地图选择
{
    snake_map_mode = (uint8_t *)all_mode_map[map_mode];
}

static void Snake_Data_Refresh(void) // 更新蛇坐标信息
{
    if(snake_body_dir != SNAKE_STOP)
    {
        
        switch (snake_body_dir)
        {
            case SNAKE_RIGHT:
                snake_body_data[0].dir = snake_body_data[0].dir & SNAKE_DIR_START | SNAKE_E_R;
                break;

            case SNAKE_LIFT:
                snake_body_data[0].dir = snake_body_data[0].dir & SNAKE_DIR_START | SNAKE_E_L;
                break;

            case SNAKE_DOWN:
                snake_body_data[0].dir = snake_body_data[0].dir & SNAKE_DIR_START | SNAKE_E_D;
                break;

            case SNAKE_UP:
                snake_body_data[0].dir = snake_body_data[0].dir & SNAKE_DIR_START | SNAKE_E_U;
                break;
        }
        memmove(snake_body_data + 1, snake_body_data, (snake_body_len) * sizeof(snake_body_s));

        switch (snake_body_dir)
        {
            case SNAKE_RIGHT:
                if(snake_body_data[1].x == 15)
                    snake_body_data[0].x = 0;
                else
                    snake_body_data[0].x = snake_body_data[1].x + 1;

                snake_body_data[0].y = snake_body_data[1].y;
                
                snake_body_data[0].dir = ((snake_body_data[1].dir ^ 0x10) << 2) | SNAKE_E_R;
                break;

            case SNAKE_LIFT:
                if(snake_body_data[1].x == 0)
                    snake_body_data[0].x = 15;
                else
                    snake_body_data[0].x = snake_body_data[1].x - 1;

                snake_body_data[0].y = snake_body_data[1].y;
                
                snake_body_data[0].dir = ((snake_body_data[1].dir ^ 0x10) << 2) | SNAKE_E_L;
                break;

            case SNAKE_DOWN:
                snake_body_data[0].x = snake_body_data[1].x;

                if(snake_body_data[1].y == 7)
                    snake_body_data[0].y = 0;
                else
                    snake_body_data[0].y = snake_body_data[1].y + 1;
                    
                snake_body_data[0].dir = ((snake_body_data[1].dir ^ 0x10) << 2) | SNAKE_E_D;
                break;

            case SNAKE_UP:
                snake_body_data[0].x = snake_body_data[1].x;

                if(snake_body_data[1].y == 0)
                    snake_body_data[0].y = 7;
                else
                    snake_body_data[0].y = snake_body_data[1].y - 1;
                    
                snake_body_data[0].dir = ((snake_body_data[1].dir ^ 0x10) << 2) | SNAKE_E_U;
                break;
        }
    }
}


static void Snake_Map_Refresh(void) // 更新全屏信息：地图，蛇
{
    for(uint8_t ret = 0; ret < 8; ret ++)
    {
        memset(map_data[ret], 0, 16);
    }
    for(uint8_t ret_x = 0; ret_x < 16; ret_x ++)
    {
        uint8_t map_v_data = snake_map_mode[ret_x];
        for(uint8_t ret_y = 0; ret_y < 8; ret_y ++)
        {
            map_data[ret_y][ret_x] = map_v_data & 0x01;
            map_v_data = map_v_data >> 1;
        }
    }
    for(uint8_t ret = 0; ret <= snake_body_len; ret ++)
    {
        if(ret == 0)
            map_data[snake_body_data[ret].y][snake_body_data[ret].x] = snake_body_data[ret].dir | MAP_SNAKE_HAED;// 蛇头
        else if(ret == snake_body_len)
            map_data[snake_body_data[ret].y][snake_body_data[ret].x] = snake_body_data[ret].dir | MAP_SNAKE_TAIL;// 蛇尾格
        else
            map_data[snake_body_data[ret].y][snake_body_data[ret].x] = snake_body_data[ret].dir | MAP_SNAKE_BODY;// 蛇身
    }
}


static void Snake_Dis_Section(int x, int y, uint8_t state)
{
    if (((state & SNAKE_DIR_START) >= (0x20 << 2)) && ((state & SNAKE_DIR_END) >= 0x20)) // 起终方向均为左右
    {
        uiShowPicture(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, (uint8_t *)snake_body[x % 2], 1);
    }
    else if (((state & SNAKE_DIR_START) < (0x20 << 2)) && ((state & SNAKE_DIR_END) < 0x20)) // 起终方向均为上下
    {
        uiShowPicture(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, (uint8_t *)snake_body[y % 2 + 2], 1);
    }
    else if(((state & SNAKE_DIR_INFO) == (SNAKE_S_U | SNAKE_E_L)) || ((state & SNAKE_DIR_INFO) == (SNAKE_S_L | SNAKE_E_U)))
    {
        uiShowPicture(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, (uint8_t *)snake_body[4], 1);
    }
    else if(((state & SNAKE_DIR_INFO) == (SNAKE_S_U | SNAKE_E_R)) || ((state & SNAKE_DIR_INFO) == (SNAKE_S_R | SNAKE_E_U)))
    {
        uiShowPicture(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, (uint8_t *)snake_body[5], 1);
    }
    else if(((state & SNAKE_DIR_INFO) == (SNAKE_S_D | SNAKE_E_L)) || ((state & SNAKE_DIR_INFO) == (SNAKE_S_L | SNAKE_E_D)))
    {
        uiShowPicture(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, (uint8_t *)snake_body[6], 1);
    }
    else if(((state & SNAKE_DIR_INFO) == (SNAKE_S_D | SNAKE_E_R)) || ((state & SNAKE_DIR_INFO) == (SNAKE_S_R | SNAKE_E_D)))
    {
        uiShowPicture(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, (uint8_t *)snake_body[7], 1);
    }
}

static void Snake_Body_Dis_Section(int x, int y, uint8_t state, uint8_t frame) // 推送全屏显示信息
{
    switch (state & 0x0f)
    {
        case MAP_ROAD:
            uiDrawBlock(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, 0);
            break;
        case MAP_WALL:
            uiDrawBlock(MAP_BLOCK_SIZE * x, MAP_BLOCK_SIZE * y, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE, 1);
            break;
        case MAP_SNAKE_BODY:
            Snake_Dis_Section(x, y, state);
            break;
        case MAP_SNAKE_HAED:
            Snake_Dis_Section(x, y, state);
            break;
        case MAP_SNAKE_TAIL:
            Snake_Dis_Section(x, y, state);
            break;
    }
}

static void Snake_Head_Dis_Section(uint8_t state, uint8_t frame) // 推送全屏显示信息
{
    int x0 = snake_body_data[0].x, y0 = snake_body_data[0].y;
    int x1 = snake_body_data[1].x, y1 = snake_body_data[1].y;

    if((state & SNAKE_DIR_START) == SNAKE_S_U)
    {
        if(frame < 3)
        {
            uiSetDisWindows(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
            uiDrawBlock(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1 + 3 + frame, MAP_BLOCK_SIZE, 3 - frame, 0);
            uiShowPicture(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1 + 3 + frame, 5, 4, snake_head_u, 1);
            // uiDrawBlock(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1 + 3 + frame, 5, 4, 1);
            uiClearDisWindows();
        }
        uiSetDisWindows(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
        uiDrawBlock(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0  - 3 + frame, MAP_BLOCK_SIZE, 9 - frame, 0);
        uiShowPicture(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0 - 3 + frame, 5, 4, snake_head_u, 1);
        // uiDrawBlock(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0 - 3 + frame, 5, 4, 1);
        uiClearDisWindows();
    }
    else if((state & SNAKE_DIR_START) == SNAKE_S_D)
    {
        if(frame < 3)
        {
            uiSetDisWindows(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
            uiDrawBlock(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1, MAP_BLOCK_SIZE, 3 - frame, 0);
            uiShowPicture(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1 - 1 - frame, 5, 4, snake_head_d, 1);
            // uiDrawBlock(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1 - 1 - frame, 5, 4, 1);
            uiClearDisWindows();
        }
        uiSetDisWindows(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
        uiDrawBlock(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0, MAP_BLOCK_SIZE, 9 - frame, 0);
        uiShowPicture(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0 + 5 - frame, 5, 4, snake_head_d, 1);
        // uiDrawBlock(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0 + 5 - frame, 5, 4, 1);
        uiClearDisWindows();
    }
    else if((state & SNAKE_DIR_START) == SNAKE_S_L)
    {
        if(frame < 3)
        {
            uiSetDisWindows(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
            uiDrawBlock(MAP_BLOCK_SIZE * x1 + 3 + frame, MAP_BLOCK_SIZE * y1, 3 - frame, MAP_BLOCK_SIZE, 0);
            uiShowPicture(MAP_BLOCK_SIZE * x1 + 3 + frame, MAP_BLOCK_SIZE * y1, 4, 5, snake_head_l, 1);
            // uiDrawBlock(MAP_BLOCK_SIZE * x1 + 3 + frame, MAP_BLOCK_SIZE * y1, 4, 5, 1);
            uiClearDisWindows();
        }
        uiSetDisWindows(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
        uiDrawBlock(MAP_BLOCK_SIZE * x0  - 3 + frame, MAP_BLOCK_SIZE * y0, 9 - frame, MAP_BLOCK_SIZE, 0);
        uiShowPicture(MAP_BLOCK_SIZE * x0 - 3 + frame, MAP_BLOCK_SIZE * y0, 4, 5, snake_head_l, 1);
        // uiDrawBlock(MAP_BLOCK_SIZE * x0 - 3 + frame, MAP_BLOCK_SIZE * y0, 4, 5, 1);
        uiClearDisWindows();
    }
    else if((state & SNAKE_DIR_START) == SNAKE_S_R)
    {
        if(frame < 3)
        {
            uiSetDisWindows(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
            uiDrawBlock(MAP_BLOCK_SIZE * x1, MAP_BLOCK_SIZE * y1, 3 - frame, MAP_BLOCK_SIZE, 0);
            uiShowPicture(MAP_BLOCK_SIZE * x1 - 1 - frame, MAP_BLOCK_SIZE * y1, 4, 5, snake_head_r, 1);
            // uiDrawBlock(MAP_BLOCK_SIZE * x1 - 1 - frame, MAP_BLOCK_SIZE * y1, 4, 5, 1);
            uiClearDisWindows();
        }
        uiSetDisWindows(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0, MAP_BLOCK_SIZE, MAP_BLOCK_SIZE);
        uiDrawBlock(MAP_BLOCK_SIZE * x0, MAP_BLOCK_SIZE * y0, 9 - frame, MAP_BLOCK_SIZE, 0);
        uiShowPicture(MAP_BLOCK_SIZE * x0 + 5 - frame, MAP_BLOCK_SIZE * y0, 4, 5, snake_head_r, 1);
        // uiDrawBlock(MAP_BLOCK_SIZE * x0 + 5 - frame, MAP_BLOCK_SIZE * y0, 4, 5, 1);
        uiClearDisWindows();
    }
}

void Snake_Game_Loop(kkui_menu_event_e event, char* tab_name, void* param)
{    
    if(event == ENTER_TAG)
    {
        uiDisClear(0);
        snake_frame = 0;
        snake_time_frame = 0;
        snake_body_dir = SNAKE_STOP;
        Snake_Body_Init();
        Snake_Map_Init(snake_mode_select);
        Snake_Data_Refresh();
        Snake_Map_Refresh();
    }
    if(event == LOOP_RUN)
    {
        if(snake_frame > 5) // 前进一格
        {
            snake_frame = 0;
            Snake_Data_Refresh();
            Snake_Map_Refresh();
        }

        for(int ret_x = 0; ret_x < 16; ret_x ++)
        {
            for(int ret_y = 0; ret_y < 8; ret_y ++)
            {
                Snake_Body_Dis_Section(ret_x, ret_y, map_data[ret_y][ret_x], snake_frame);
            }
        }
        Snake_Head_Dis_Section(map_data[snake_body_data[0].y][snake_body_data[0].x], snake_frame);
        // Snake_Tail_Dis_Section(ret_x, ret_y, map_data[ret_y][ret_x], snake_frame);

        if(snake_body_dir != SNAKE_STOP)
        {
            if(uiKeyGetValue(UI_KEY_UP_ID) == DOWN && snake_body_dir != SNAKE_DOWN && (snake_body_data[0].dir & SNAKE_DIR_START) != SNAKE_S_U)
            {
                snake_body_dir = SNAKE_UP;
                // snake_frame = 5;
            }
            if(uiKeyGetValue(UI_KEY_DOWN_ID) == DOWN && snake_body_dir != SNAKE_UP && (snake_body_data[0].dir & SNAKE_DIR_START) != SNAKE_S_D)
            {
                snake_body_dir = SNAKE_DOWN;
                // snake_frame = 5;
            }
            if(uiKeyGetValue(UI_KEY_LEFT_ID) == DOWN && snake_body_dir != SNAKE_RIGHT && (snake_body_data[0].dir & SNAKE_DIR_START) != SNAKE_S_L)
            {
                snake_body_dir = SNAKE_LIFT;
                // snake_frame = 5;
            }
            if(uiKeyGetValue(UI_KEY_RIGHT_ID) == DOWN && snake_body_dir != SNAKE_LIFT && (snake_body_data[0].dir & SNAKE_DIR_START) != SNAKE_S_R)
            {
                snake_body_dir = SNAKE_RIGHT;
                // snake_frame = 5;
            }
        }
        if(uiKeyGetValue(UI_KEY_ENTER_ID) == DOWN)
        {
            if(snake_body_dir != SNAKE_STOP)
                snake_body_dir = SNAKE_STOP;
            else
                snake_body_dir = ((snake_body_data[0].dir & SNAKE_DIR_END) >> 4) + 1;
        }
        if(uiKeyGetValue(UI_KEY_BACK_ID) == DOWN)
        {
            uiBackAppLoop();
        }

        if(snake_body_dir)
        {
            snake_time_frame ++;
        }
        if(snake_time_frame > (6 - snake_level_select))
        {
            snake_time_frame = 0;
            snake_frame ++;
        }
    }
}




typedef struct
{
    char name[20];
    int score;
    int time;
}snake_record_s;

snake_record_s snake_record[5] =
{
    {"ligoud",  25,     10},
    {"chenhz",  22,     10},
    {"wangty",  21,     10},
    {"tianl",   5,      10},
    {"tianl",   1,      10},
};

void Snake_Record_Loop(kkui_menu_event_e event, char* tab_name, void* param)
{    
    if(event == ENTER_TAG)
    {
        uiDisClear(0);
    }
    if(event == LOOP_RUN)
    {
        char dis_buf[24];
        uiShowString(0, 2, (char *)"用户名         得分", 12, 1);
        for(uint8_t ret = 0; ret < 5; ret ++)
        {
            memset(dis_buf, 0, 24);
            sprintf(dis_buf, "%s", snake_record[ret].name);
            uiShowString(0, 16 + 9 * ret, dis_buf, 8, 1);
            memset(dis_buf, 0, 24);
            sprintf(dis_buf, "%d", snake_record[ret].score);
            uiShowString(90, 16 + 9 * ret, dis_buf, 8, 1);
        }
        if(uiKeyGetValue(UI_KEY_BACK_ID) == DOWN)
        {
            uiBackAppLoop();
        }
    }
}
